/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-05-12     刘奇辉       the first version
 */
#ifndef APPLICATIONS_MAIN_CONTEXTMODULE_OTAMODE_H_
#define APPLICATIONS_MAIN_CONTEXTMODULE_OTAMODE_H_

#include "rtthread.h"
#include "main.h"                  //main.h会自动导入大多数的HAL库的.h文件
#include "rtdevice.h"
#include "stm32_hal_legacy.h"
#include "dev_4gmodule.h"

#define STM32FLASH_SIZE        0x00040000UL                                    /* FLASH大小：256K */
#define STM32FLASH_BASE        FLASH_BASE                                      /* FLASH起始地址 */
#define STM32FLASH_END         (STM32FLASH_BASE | STM32FLASH_SIZE)             /* FLASH结束地址 */
#define STM32FLASH_PAGE_SIZE   FLASH_PAGE_SIZE                                 /* FLASH页大小：2K */
#define STM32FLASH_PAGE_NUM    (STM32FLASH_SIZE / STM32FLASH_PAGE_SIZE)        /* FLASH总页数 */
#define ADDR_FLASH_PAGE_X(X)   (STM32FLASH_BASE | (X * STM32FLASH_PAGE_SIZE))  /* 获取页地址，X=0~STM32FLASH_PAGE_NUM */
#define STM32_FLASH  1                                                         /*选择启用的功能*/

#define MSG_REV_BUF_SIZE                    (2048)  //1024字节存储Bin程序的一部分+帧头+校验码
#define DOWNLOAD_DATA_BLOCK_SIZE            (952)      //1024字节存储Bin程序的一部分

#define BOOTLOADER_FLASH_SIZE               ((uint32_t)0x00006800)              //26kb
#define APPLICATION_FLASH_SIZE              ((uint32_t)0x0001B800)              //110kb
#define DOWNLOAD_FLASH_SIZE                 ((uint32_t)0x0001B800)              //110kb
#define PARAMETERS_FLASH_SIZE               ((uint32_t)0x00002800)              //10kb


#define FLASH_START_ADDR                    ((uint32_t)0x08000000)                                          //Flash起始地址
#define FLASH_ADDR_BOOTLOADER               ((uint32_t)FLASH_START_ADDR)                                    //Bootloader起始地址(Flash起始地址)
#define FLASH_ADDR_APPLICATION              ((uint32_t)(FLASH_ADDR_BOOTLOADER+BOOTLOADER_FLASH_SIZE))       //app下载地址
#define FLASH_ADDR_DOWNLOAD_DATA            ((uint32_t)(FLASH_ADDR_APPLICATION+APPLICATION_FLASH_SIZE))     //下载固件存储地址
#define FLASH_ADDR_PARAMETERS               ((uint32_t)(FLASH_ADDR_DOWNLOAD_DATA+DOWNLOAD_FLASH_SIZE))      //参数存放存储地址




struct otaversion
{
    int ota_MajorVersion; /*主版本*/
    int ota_ChildVersion; /*子版本*/
    int ota_ReVision; /*修订版本*/
};
typedef struct otaversion otaversion_t;

//该结构体不需要读，只需要写入，在bootloader读出app写入的信息进行判断是否需要升级
struct  typeofUpdateInfo{
    uint32_t flag;                         //0:表示不需要更新   1：表示有升级包
    uint32_t runRelease;                   //存储正在运行的app版本
    uint32_t downloadRelease;              //存储已经下载的ota升级包版本
    uint32_t downloadSize;                 //存储已经下载的ota升级包大小(字节)
};

struct  typeofDownloadInfo
{
   char        id[20];
   uint32_t    ota_VersionNumber;     /*当前软件版本号 0.1.1-> 0*10000+1*100+1=000101;*/

   uint32_t    downloadRelease;
   uint32_t    ota_size;              /*升级包大小 */
   uint32_t    ota_byte_size;         /*升级下载字节控制*/
   uint8_t     ota_crc[32];           /*升级包校验码*/
   char        ota_url[128];          /*文件下载URL-HTTP*/
   char        ota_route[128];        /*文件下载目录-HTTP*/
   char ota_port[6];

};
typedef struct  typeofDownloadInfo  *typeofDownloadInfo_t;
//存放http服务器返回的数据
struct OTAMsgBuf
{
    uint8_t buf[MSG_REV_BUF_SIZE];
    uint16_t msgLen;
};
void ota_notify(void);
uint32_t get_Version();
uint8_t otaStatusGet();

void onRevOTAFrame(uint8_t *frameData, rt_size_t frameSize);       //MQTT获取数据帧需要调用的函数
void otaModeThreadStop();                                               //终止OTA线程
void otaThreadEntry(void *para);                                        //OTA线程执行函数
uint8_t WriteApplicationDataToFlash(uint32_t Address,uint8_t* data, uint32_t len);   //缺少擦除的flash写函数
uint8_t otaDownloadFirmware(struct typeofDownloadInfo* otaInfo, uint8_t socket, uint32_t firmwareSize, uint32_t timeoutMs,
        const uint16_t retryNum);
int EraseDownloadSpace(void);
uint32_t otaVersinToint(otaversion_t* version);
otaversion_t otaVersinToStuct(uint32_t version);

typeofDownloadInfo_t ota_get_info_struct();



#endif /* APPLICATIONS_MAIN_CONTEXTMODULE_OTAMODE_H_ */
